package com.ushine.web.communication.des.server;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @Author: yls
 * @Date 2022/5/6 11:11
 * @Description: RSA加密工具类
 * @Version 1.0
 **/
@Slf4j
public class NetworkRsaUtils {

    private NetworkRsaUtils() {
    }

    /**
     * 加密算法
     */
    private static final String ENCRYPT_ALGORITHM = "RSA";

    /**
     * 加密算法
     */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 秘钥长度
     */
    private static final Integer KEY_LENGTH = 2048;

    /**
     * 功能描述:
     * 〈 随机生成秘钥对 〉
     *
     * @return : java.security.KeyPair
     * @throws NoSuchAlgorithmException 未知算法异常
     * @author : yls
     * @date : 2022/5/6 11:14
     */
    public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator rsa = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        rsa.initialize(KEY_LENGTH);
        return rsa.generateKeyPair();
    }

    /**
     * 功能描述:
     * 〈 获取公钥 〉
     *
     * @param keypair 秘钥器
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/5/6 11:19
     */
    public static String getPublicKey(KeyPair keypair) {
        PublicKey publicKey = keypair.getPublic();
        byte[] encoded = publicKey.getEncoded();
        return Base64Utils.byte2Base64(encoded);
    }

    /**
     * 功能描述:
     * 〈 获取公钥 〉
     *
     * @param keypair 秘钥器
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/5/6 11:19
     */
    public static String getPrivateKey(KeyPair keypair) {
        PrivateKey privateKey = keypair.getPrivate();
        byte[] encoded = privateKey.getEncoded();
        return Base64Utils.byte2Base64(encoded);
    }


    /**
     * 功能描述:
     * 〈 将Base64编码后的公钥转换成PublicKey对象 〉
     *
     * @param pubStr 公钥字符串
     * @return : java.security.PublicKey
     * @author : yls
     * @date : 2022/5/6 11:20
     */
    public static PublicKey string2PublicKey(String pubStr) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
        byte[] keyBytes = Base64Utils.base642Byte(pubStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    /**
     * 功能描述:
     * 〈将Base64编码后的私钥转换成PrivateKey对象〉
     *
     * @param priStr 私钥字符串
     * @return : java.security.PrivateKey
     * @author : yls
     * @date : 2022/5/6 11:20
     */
    public static PrivateKey string2PrivateKey(String priStr) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = Base64Utils.base642Byte(priStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 功能描述:
     * 〈公钥加密〉
     *
     * @param content   待加密的内容
     * @param publicKey 公钥加密
     * @return : byte[]
     * @throws Exception 系统异常
     * @author : yls
     * @date : 2022/5/6 11:22
     */
    public static String publicEncrypt(byte[] content, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] bytes = cipher.doFinal(content);
        return Base64Utils.byte2Base64(bytes);
    }

    /**
     * 功能描述:
     * 〈私钥解密〉
     *
     * @param content    带解密的内容
     * @param privateKey 私钥
     * @return : byte[]
     * @throws Exception 系统异常
     * @author : yls
     * @date : 2022/5/6 11:21
     */
    public static String privateDecrypt(String content, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, IOException {
        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] contentBytes = Base64Utils.base642Byte(content);
        byte[] bytes = cipher.doFinal(contentBytes);
        // 解密
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 功能描述:
     * 〈私钥解密〉
     *
     * @param content    带解密的内容
     * @param privateKey 私钥
     * @return : byte[]
     * @throws Exception 系统异常
     * @author : yls
     * @date : 2022/5/6 11:21
     */
    public static byte[] privateBytesDecrypt(String content, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, IOException {
        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] contentBytes = Base64Utils.base642Byte(content);
        return cipher.doFinal(contentBytes);
    }


}
